今天我們來看
abstract class Model
裡面到底是怎麼將對物件的存取轉換成對資料庫的存取的
Model
裡面 find()
的實作如下
/**
* Find a model by its primary key.
*
* @param mixed $id
* @param array|string $columns
* @return ($id is (\Illuminate\Contracts\Support\Arrayable<array-key, mixed>|array<mixed>) ? \Illuminate\Database\Eloquent\Collection<int, TModel> : TModel|null)
*/
public function find($id, $columns = ['*'])
{
if (is_array($id) || $id instanceof Arrayable) {
return $this->findMany($id, $columns);
}
return $this->whereKey($id)->first($columns);
}
我們這邊先看 find()
輸入值為一個的狀況,所以會取用到 whereKey()
whereKey()
的實作則是
/**
* Add a where clause on the primary key to the query.
*
* @param mixed $id
* @return $this
*/
public function whereKey($id)
{
if ($id instanceof Model) {
$id = $id->getKey();
}
if (is_array($id) || $id instanceof Arrayable) {
if (in_array($this->model->getKeyType(), ['int', 'integer'])) {
$this->query->whereIntegerInRaw($this->model->getQualifiedKeyName(), $id);
} else {
$this->query->whereIn($this->model->getQualifiedKeyName(), $id);
}
return $this;
}
if ($id !== null && $this->model->getKeyType() === 'string') {
$id = (string) $id;
}
return $this->where($this->model->getQualifiedKeyName(), '=', $id);
}
where()
則是
/**
* Add a basic where clause to the query.
*
* @param (\Closure(static): mixed)|string|array|\Illuminate\Contracts\Database\Query\Expression $column
* @param mixed $operator
* @param mixed $value
* @param string $boolean
* @return $this
*/
public function where($column, $operator = null, $value = null, $boolean = 'and')
{
if ($column instanceof Closure && is_null($operator)) {
$column($query = $this->model->newQueryWithoutRelationships());
$this->query->addNestedWhereQuery($query->getQuery(), $boolean);
} else {
$this->query->where(...func_get_args());
}
return $this;
}
這裡會使用到 $this->query
,$this->query
的型別是
/**
* The base query builder instance.
*
* @var \Illuminate\Database\Query\Builder
*/
protected $query;
追到這邊我們會發現,Eloquent\Builder
到後面,底層依舊是使用 Query\Builder
進行實作的。
仔細想想也會發現這樣很合理,畢竟我們已經寫了一段生成 SQL Query 的邏輯,我們不需要重新再寫一次。只要讓 Model
裡面所使用的 Eloquent\Builder
包含 Query\Builder
即可。
剩下的部分,我們明天再來看!